package blackstar.plugin.monitor;

import java.sql.Timestamp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import blackstar.agent.event.EventDispatcherSupport;
import blackstar.agent.jvm.JMXProxy;
import blackstar.agent.jvm.JMXProxyErrorEvent;
import blackstar.plugin.monitor.reporter.ReportData;
import blackstar.plugin.monitor.reporter.ResultReporter;

/**
 * @author raywu (ayufox@gmail.com)
 * 
 */
public abstract class AbstractMonitor extends EventDispatcherSupport implements Monitor
{
	protected final Log LOGGER = LogFactory.getLog(getClass());

	private boolean isInitSuccess = false;
	private String jvmid;
	private String id = "default";
	private ResultReporter resultReporter;
	private JMXProxy jmxProxy;

	public AbstractMonitor()
	{
	}

	public AbstractMonitor(String id)
	{
		this.id = id;
	}

	public String getName()
	{
		return this.id;
	}

	public void setResultReporter(ResultReporter resultReporter)
	{
		this.resultReporter = resultReporter;
	}

	public void setSuccess()
	{
		this.isInitSuccess = true;
	}

	public void init(JMXProxy jmxProxy)
	{
		try
		{
			this.jvmid = jmxProxy.getId();

			doInit(jmxProxy);

			setSuccess();
			LOGGER.info("init success");
		} catch (Exception e)
		{
			LOGGER.error("Init failed", e);
		}
		
		this.jmxProxy = jmxProxy;
	}

	public void onTimeout()
	{
		if (this.isInitSuccess)
		{
			try
			{
				doOnTimeout();
			} catch (Exception e)
			{
				LOGGER
						.error("doOnTimeout failed",
								e);
				dispatch(new JMXProxyErrorEvent(this.jmxProxy));
			}
		}
	}

	public void destroy()
	{
		try
		{
			doDestroy();
		} catch (Exception e)
		{
			LOGGER.error("destroy failed", e);
		}
	}

	protected void report(long data)
	{
		report(this.id, data);
	}

	protected void report(String id, long data)
	{
		Timestamp timestamp = new Timestamp(System.currentTimeMillis());
		ReportData reportData = new ReportData(this.jvmid, id, data, timestamp);
		this.resultReporter.report(reportData);

		LOGGER.info("report[" + reportData + "]");
	}

	protected abstract void doInit(JMXProxy jmxProxy) throws Exception;

	protected abstract void doOnTimeout() throws Exception;

	protected void doDestroy()
	{

	}
}
